import java.awt.event.ActionEvent;
import java.io.File;
import java.util.ArrayList;
import java.util.LinkedList;

import javax.swing.JDialog;

import net.sf.samtools.SAMFileHeader;
import net.sf.samtools.SAMFileReader;
import net.sf.samtools.SAMRecord;
import net.sf.samtools.SAMRecordIterator;
import net.sf.samtools.SAMSequenceRecord;

public class Species {

        LinkedList<Integer> numberOfReadsForRegion;
        LinkedList<Integer> numberOfGenes;
        LinkedList<Integer[]> indexGeneList;
        File bamFile;
        File index;
        GenBankParser genBankParser;

        public Species(File bamFile, File index, GenBankParser genBankParser) {
                this.bamFile = bamFile;
                this.index = index;
                this.genBankParser = genBankParser;
                this.numberOfReadsForRegion = new LinkedList<Integer>();
                this.numberOfGenes = new LinkedList<Integer>();
                this.indexGeneList = new LinkedList<Integer[]>();
                openFrame();

        }
       
        public void openFrame() {
                new FrameSequence(this, getSequenceName());
        }

        public void setNumberOfReads(String l) {

                this.indexGeneList = genBankParser.indexGeneList;
                final SAMFileReader reader = new SAMFileReader(bamFile, index);
                for (int i = 0; i < this.genBankParser.indexGeneList.size(); i++) {
                		//Iterator goes through specified interval and string (reference seq) 
                	    // Interval is made from start and end gene positions passed from index
                		// String name "1" is placeholder value that will be replaced by user
                		// once actual program is run using getSequenceDictionary/getSequenceName code below
                        SAMRecordIterator iterator = reader.queryContained(l, //CHANGE HERE
                                        this.genBankParser.indexGeneList.get(i)[0],
                                        this.genBankParser.indexGeneList.get(i)[1]);
                        // Counts all reads encountered as iterator goes through BAM files
                        int j = 0;
                        while (iterator.hasNext()) {
                                SAMRecord samRecord = iterator.next();
                                j++;
                        }
                        this.numberOfReadsForRegion.add(j);
                        this.numberOfGenes.add(i);
                        iterator.close();
                }
        }
        // Getting names of available reference sequences (chromosomes) within each BAM file
        // So that user can pick which to use with each BAM file
        public ArrayList<String> getSequenceName(){
                ArrayList<String> sequenceNameList = new ArrayList<String>();
                final SAMFileReader reader = new SAMFileReader(bamFile, index);
                SAMFileHeader Bob = reader.getFileHeader();
                for(SAMSequenceRecord ssr:Bob.getSequenceDictionary().getSequences())
                {		// Store the acquired names of available reference sequences
                        sequenceNameList.add(ssr.getSequenceName()) ;
                }		
                reader.close();
                return sequenceNameList;
               
        }
       
        public int getStartPosicion(int gene) {
                return this.indexGeneList.get(gene)[0];
        }
       
        public int getEndPosicion(int gene) {
                return this.indexGeneList.get(gene)[1];
        }
       
         public Double [] toArray(LinkedList<Integer> list){
                Double [] out = new Double [list.size()];
                for (int i = 0; i < out.length; i++) {
                        out[i] = (double)list.get(i);
                }
                return out;
        }
}

class FrameSequence extends javax.swing.JDialog {
       
    // Variables declaration - do not modify                    
    private javax.swing.JButton jButton1;
    private javax.swing.JComboBox jComboBox1;
    private javax.swing.JLabel jLabel1;
    // End of variables declaration  
   
    String result;
    Species specie;


    public FrameSequence(Species specie,ArrayList<String> listSequenceName) {
        this.specie = specie;
        initComponents(listSequenceName);
        try {
            for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (ClassNotFoundException ex) {
            java.util.logging.Logger.getLogger(FrameSequence.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
            java.util.logging.Logger.getLogger(FrameSequence.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            java.util.logging.Logger.getLogger(FrameSequence.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (javax.swing.UnsupportedLookAndFeelException ex) {
            java.util.logging.Logger.getLogger(FrameSequence.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        }
        this.setModal(true);
        this.setVisible(true);
       
    }

    // Graphics behind Box that appears after submitting all files,
    // allowing user to select which reference sequence/chromosome to use
    // for each BAM file
    private void initComponents(ArrayList<String> listSequenceName) {

        jComboBox1 = new javax.swing.JComboBox();
        jLabel1 = new javax.swing.JLabel();
        jButton1 = new javax.swing.JButton();

        jComboBox1.setModel(new javax.swing.DefaultComboBoxModel(toArray(listSequenceName)));

        jLabel1.setFont(new java.awt.Font("Tahoma", 0, 12)); // NOI18N
        jLabel1.setText("Select the region of the BAM file you want to use:");

        jButton1.setText("OK");
        jButton1
                .addActionListener(new java.awt.event.ActionListener() {
                        public void actionPerformed(
                                        java.awt.event.ActionEvent evt) {
                                jButton1ActionPerformed(evt);
                        }
                });
       

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addComponent(jButton1, javax.swing.GroupLayout.PREFERRED_SIZE, 85, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                        .addComponent(jLabel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .addComponent(jComboBox1, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addGap(33, 33, 33)
                .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 36, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(18, 18, 18)
                .addComponent(jComboBox1, javax.swing.GroupLayout.PREFERRED_SIZE, 36, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 39, Short.MAX_VALUE)
                .addComponent(jButton1, javax.swing.GroupLayout.PREFERRED_SIZE, 36, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap())
        );
        this.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);

        pack();
    }// </editor-fold>                        

        private void jButton1ActionPerformed(ActionEvent evt) {
                this.result = (String)this.jComboBox1.getSelectedItem();
                this.specie.setNumberOfReads(result);
                this.dispose();
               
        }
        public String [] toArray(ArrayList<String> list){
                String [] out = new String [list.size()];
                for (int i = 0; i < out.length; i++) {
                        out[i] = list.get(i);
                }
                return out;
        }
                 
}
